package com.hk.core.jdbc.query;

import com.hk.commons.query.AndOr;
import com.hk.commons.query.Operator;
import com.hk.commons.util.ArrayUtils;
import com.hk.commons.util.CollectionUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.util.ObjectUtils;

import java.util.Collection;

/**
 * @author Kevin
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public abstract class Conditions {

    /**
     * where field = ?
     *
     * @param field field
     * @param value value
     */
    public static Condition eq(String field, Object value) {
        return ObjectUtils.isEmpty(value) ? null : new SimpleCondition(field, Operator.EQ, value);
    }

    /**
     * where field <> ?
     *
     * @param field field
     * @param value value
     */
    public static Condition ne(String field, Object value) {
        return ObjectUtils.isEmpty(value) ? null : new SimpleCondition(field, Operator.NE, value);
    }

    /**
     * where field like '?'
     *
     * @param field field
     * @param value value
     */
    public static Condition like(String field, CharSequence value) {
        return newCondition(field, Operator.LIKE, value);
    }

    /**
     * where field like '%?%'
     *
     * @param field field
     * @param value value
     */
    public static Condition likeAnywhere(String field, CharSequence value) {
        return newCondition(field, Operator.LIKE_ANYWHERE, value);
    }

    /**
     * where field not like '%?%'
     *
     * @param field field
     * @param value value
     */
    public static Condition notLikeAnywhere(String field, CharSequence value) {
        return newCondition(field, Operator.NOT_LIKE_ANYWHERE, value);
    }

    /**
     * where field like '?%'
     *
     * @param field field
     * @param value value
     */
    public static Condition likeStart(String field, CharSequence value) {
        return newCondition(field, Operator.LIKE_START, value);
    }

    /**
     * where field like '%?'
     *
     * @param field field
     * @param value value
     */
    public static Condition likeEnd(String field, CharSequence value) {
        return newCondition(field, Operator.LIKE_END, value);
    }

    public static Condition newCondition(String field, Operator operator, Object value) {
        return ObjectUtils.isEmpty(value) ? null : new SimpleCondition(field, operator, value);
    }

    /**
     * where field > ?
     *
     * @param field field
     * @param value value
     */
    public static <T extends Comparable<? super T>> Condition gt(String field, T value) {
        return newCondition(field, Operator.GT, value);
    }

    /**
     * where field >= ?
     *
     * @param field field
     * @param value value
     */
    public static <T extends Comparable<? super T>> Condition gte(String field, T value) {
        return newCondition(field, Operator.GTE, value);
    }

    /**
     * where field < ?
     *
     * @param field field
     * @param value value
     */
    public static <T extends Comparable<? super T>> Condition lt(String field, T value) {
        return newCondition(field, Operator.LT, value);
    }

    /**
     * where field  <= ?
     *
     * @param field field
     * @param value value
     */
    public static <T extends Comparable<? super T>> Condition lte(String field, T value) {
        return newCondition(field, Operator.LTE, value);
    }

    /**
     * where field between ? and ?
     *
     * @param field  field
     * @param value1 value1
     * @param value2 value2
     */
    public static <T extends Comparable<? super T>> Condition between(String field, T value1, T value2) {
        return ObjectUtils.isEmpty(value1) || ObjectUtils.isEmpty(value2) ? null : new SimpleCondition(field,
                Operator.BETWEEN, new Object[]{value1, value2});
    }

    /**
     * where field in (?,?...)
     *
     * @param field  field
     * @param values values
     */
    public static Condition in(String field, Object... values) {
        return in(field, ArrayUtils.asArrayList(values));
    }

    /**
     * where field in (?,?...)
     *
     * @param field field
     * @param value value
     */
    public static Condition in(String field, Collection<?> value) {
        return CollectionUtils.isEmpty(value) ? null : new SimpleCondition(field, Operator.IN, value);
    }

    /**
     * where field not in (?,?...)
     *
     * @param field  field
     * @param values values
     */
    public static Condition notIn(String field, Object... values) {
        return notIn(field, ArrayUtils.asArrayList(values));
    }

    /**
     * where field not in (?,?...)
     *
     * @param field field
     * @param value value
     */
    public static Condition notIn(String field, Collection<?> value) {
        return CollectionUtils.isEmpty(value) ? null : new SimpleCondition(field, Operator.NOT_IN, value);
    }

    /**
     * where field IS NULL
     *
     * @param field field
     */
    public static Condition isNull(String field) {
        return new SimpleCondition(field, Operator.IS_NULL, null);
    }

    /**
     * where field IS NULL OR field = ''
     *
     * @param field field
     */
    public static Condition isNullOrEmpty(String field) {
        return new SimpleCondition(field, Operator.IS_NULL_OR_EMPTY, null);
    }

    /**
     * where field IS NOT NULL
     *
     * @param field field
     */

    public static Condition isNotNull(String field) {
        return new SimpleCondition(field, Operator.IS_NOT_NULL, null);
    }

    public static Condition or(Condition... conditions) {
        if (ArrayUtils.isEmpty(conditions)) {
            return null;
        }
        CompositeCondition c = new CompositeCondition();
        c.setAndOr(AndOr.OR);
        c.addConditions(conditions);
        return c;
    }

}
